<?php
// +----------------------------------------------------------------------
// | 模型
// +----------------------------------------------------------------------
declare(strict_types=1);

namespace app\model;

use think\Model;
use think\db\Query;

/**
 * 系统用户模型
 *
 * Class SystemUsersModel
 * @package app\model
 * @OA\Schema(
 *   schema="GetSystemUsers",
 *   type="object",
 *   @OA\Property(description="ID", property="id", type="integer", example=1),
 *   @OA\Property(
 *     description="部门详情", 
 *     property="depts",
 *     type="array",
 *     @OA\Items(ref="#/components/schemas/GetSystemDepts")
 *   ),
 *   @OA\Property(
 *     description="角色详情", 
 *     property="roles",
 *     type="array",
 *     @OA\Items(ref="#/components/schemas/GetSystemRoles")
 *   ),
 *   @OA\Property(description="账号", property="username", type="string", example="admin"),
 *   @OA\Property(description="昵称", property="nickname", type="string", example="管理员"),
 *   @OA\Property(description="手机", property="phone", type="string", example="13800138000"),
 *   @OA\Property(description="邮箱", property="email", type="string", example="tss@admin.com"),
 *   @OA\Property(description="备注", property="remark", type="string", example="备注信息"),
 *   @OA\Property(description="排序", property="sort", type="integer", example=10),
 *   @OA\Property(description="状态", property="status", type="boolean", example=true),
 *   @OA\Property(description="创建时间", property="createTime", type="string", format="date-time", example="2024-01-01T12:00:00Z"),
 *   @OA\Property(description="更新时间", property="updateTime", type="string", format="date-time", example="2024-01-02T12:00:00Z")
 * )
 * @OA\Schema(
 *   schema="SetSystemUsers",
 *   type="object",
 *   @OA\Property(
 *     description="所属部门ID",
 *     property="depts",
 *     type="array",
 *     items={@OA\Items(type="integer")},
 *     example={1, 2}
 *   ),
 *   @OA\Property(description="账号", property="username", type="string", example="admin"),
 *   @OA\Property(description="昵称", property="nickname", type="string", example="管理员"),
 *   @OA\Property(description="密码（仅新增）", property="password", type="string", example=""),
 *   @OA\Property(description="手机", property="phone", type="string", example="13800138000"),
 *   @OA\Property(description="邮箱", property="email", type="string", example="tss@admin.com"),
 *   @OA\Property(description="备注", property="remark", type="string", example="备注信息"),
 *   @OA\Property(description="排序", property="sort", type="integer", example=10),
 *   @OA\Property(description="状态", property="status", type="boolean", example=true)
 * )
 */
class SystemUsersModel extends Model
{
    // 设置表名
    protected $name = 'system_users';
    // 设置字段信息
    protected $schema = [
        'id'          => 'int',
        // 账号
        'username'    => 'string',
        // 昵称
        'nickname'    => 'string',
        // 密码
        'password'    => 'string',
        // 手机
        'phone'       => 'string',
        // 邮箱
        'email'       => 'string',
        // 备注
        'remark'      => 'string',
        // 排序
        'sort'        => 'int',
        // 状态
        'status'      => 'bool',
        // 创建时间
        'create_time' => 'datetime',
        // 更新时间
        'update_time' => 'datetime',
    ];
    // 模型数据不区分大小写
    protected $strict = false;
    // 数据转换为驼峰命名
    protected $convertNameToCamel = true;
    // 移除关联字段
    protected $hidden = ['pivot'];

    /**
     * 获取完整数据（包含关联与排序）
     * 
     * @return Query
     */
    static public function queryOrder()
    {
        return self::with(['depts' => function (Query $query) {
            $query->where('status', true);
        }, 'roles' => function (Query $query) {
            $query->where('status', true);
        }])->order([
            'sort' => 'asc',
            'id'   => 'asc'
        ]);
    }

    /**
     * 过滤禁用的关联数据
     * 
     * @return array
     */
    static public function filterRelations(array $data, bool $is_list): array
    {
        if ($is_list) {
            foreach ($data as $key => $value) {
                $data[$key] = self::filterRelations($value, false);
            }
        } else {
            if (!empty($data['roles'])) {
                $data['roles'] = array_filter($data['roles'], function ($carry, $item) {
                    if ($item['status'] !== false) {
                        $carry[] = $item;
                    }
                    return $carry;
                });
            }
            if (!empty($data['depts'])) {
                $data['depts'] = array_filter($data['depts'], function ($carry, $item) {
                    if ($item['status'] !== false) {
                        $carry[] = $item;
                    }
                    return $carry;
                });
            }
        }
        return $data;
    }

    /**
     * 多对多关联 - 角色
     * 
     * @return
     */
    public function roles()
    {
        return $this->belongsToMany(SystemRolesModel::class, SystemUsersRolesPivot::class, 'role_id', 'user_id');
    }

    /**
     * 多对多关联 - 部门
     * 
     * @return
     */
    public function depts()
    {
        return $this->belongsToMany(SystemDeptsModel::class, SystemUsersDeptsPivot::class, 'dept_id', 'user_id');
    }

    /**
     * 搜索器 - 部门ID
     * 
     * @param Query $query 请求
     * @param mixed $value 字段值
     * @param array $data 完整数据
     * @return
     */
    public function searchDeptIdAttr($query, $value, $data)
    {
        $ids = SystemUsersDeptsPivot::where('dept_id', $value)->column('user_id');
        $query->whereIn('id', $ids);
    }

    /**
     * 搜索器 - 账号
     * 
     * @param Query $query 请求
     * @param mixed $value 字段值
     * @param array $data 完整数据
     * @return
     */
    public function searchUsernameAttr($query, $value, $data)
    {
        $query->where('username', 'like', '%' . $value . '%');
    }

    /**
     * 搜索器 - 昵称
     * 
     * @param Query $query 请求
     * @param mixed $value 字段值
     * @param array $data 完整数据
     * @return
     */
    public function searchNicknameAttr($query, $value, $data)
    {
        $query->where('nickname', 'like', '%' . $value . '%');
    }

    /**
     * 搜索器 - 手机
     * 
     * @param Query $query 请求
     * @param mixed $value 字段值
     * @param array $data 完整数据
     * @return
     */
    public function searchPhoneAttr($query, $value, $data)
    {
        $query->where('phone', 'like', '%' . $value . '%');
    }

    /**
     * 搜索器 - 邮箱
     * 
     * @param Query $query 请求
     * @param mixed $value 字段值
     * @param array $data 完整数据
     * @return
     */
    public function searchEmailAttr($query, $value, $data)
    {
        $query->where('email', 'like', '%' . $value . '%');
    }

    /**
     * 搜索器 - 备注
     * 
     * @param Query $query 请求
     * @param mixed $value 字段值
     * @param array $data 完整数据
     * @return
     */
    public function searchRemarkAttr($query, $value, $data)
    {
        $query->where('remark', 'like', '%' . $value . '%');
    }

    /**
     * 搜索器 - 状态
     * 
     * @param Query $query 请求
     * @param mixed $value 字段值
     * @param array $data 完整数据
     * @return
     */
    public function searchStatusAttr($query, $value, $data)
    {
        $query->where('status', !!$value);
    }

    /**
     * 获取器 - 状态
     *
     * @param mixed $value
     * @return array
     */
    public function getStatusAttr($value)
    {
        return !!$value;
    }

    /**
     * 修改器 - 密码
     * 
     * @param mixed $value 字段值
     * @return
     */
    public function setPasswordAttr($value)
    {
        return encryptPassword($value);
    }

    /**
     * 修改器 - 状态
     *
     * @param mixed $value
     * @return int
     */
    public function setStatusAttr($value)
    {
        return !!$value;
    }

    /**
     * 删除事件
     * 
     * @param mixed $data 完整数据
     * @return
     */
    public static function onAfterDelete($data)
    {
        SystemUsersDeptsPivot::destroy(function ($query) use ($data) {
            $query->where('user_id', $data->id);
        });
        SystemUsersRolesPivot::destroy(function ($query) use ($data) {
            $query->where('user_id', $data->id);
        });
        SystemUsersMessagesModel::destroy(function ($query) use ($data) {
            $query->where('user_id', $data->id);
        });
    }
}
